﻿// 认证工具函数 - 中医适宜技术防控青少年近视系统
// 设计说明：
// 1. 所有登录/注册/绑定操作均在此集中，避免页面分散直接访问 wx.request。
// 2. computeUserStatus 负责归一化 userInfo：
//    - 兼容后端可能返回 student 或 studentInfo 字段
//    - 统一写回 storage，减少各页面重复判断
// 3. 绑定成功状态的枚举集中在 BIND_SUCCESS_STATUSES，杜绝多处硬编码。
// 4. 所有对 token 的读取统一通过 getToken，便于后续替换持久化策略（如Session刷新）。

const BIND_SUCCESS_STATUSES = ['confirmed', 'bound', 'success'];

/**
 * 获取API基础URL
 */
const getApiBaseUrl = () => {
  const app = getApp();
  
  // 如果app还没有初始化完成，手动调用环境检测
  if (!app.globalData.apiBaseUrl) {
    console.log('app.globalData.apiBaseUrl 未设置，手动检测环境');
    
    // 判断是否在微信开发者工具中
    const systemInfo = wx.getSystemInfoSync();
    const isDeveloperTool = systemInfo.platform === 'devtools';
    
    console.log('系统信息:', systemInfo);
    console.log('是否为开发工具:', isDeveloperTool);
    
    if (isDeveloperTool) {
      // 开发环境
      app.globalData.apiBaseUrl = 'http://localhost:5000/api/miniprogram';
      console.log('设置为开发环境地址:', app.globalData.apiBaseUrl);
    } else {
      // 生产环境
      app.globalData.apiBaseUrl = 'https://vision.skyantkj.com/api/miniprogram';
      console.log('设置为生产环境地址:', app.globalData.apiBaseUrl);
    }
  }
  
  console.log('最终API地址:', app.globalData.apiBaseUrl);
  return app.globalData.apiBaseUrl;
};

/**
 * 微信登录函数
 * @param {string} code 微信登录code
 * @returns {Promise<Object>} 返回登录结果
 */
const wechatLogin = (code) => {
  return new Promise((resolve, reject) => {
    wx.request({
      url: `${getApiBaseUrl()}/auth/wechat_login`,
      method: 'POST',
      data: { code },
      success: (response) => {
        if (response.data && response.data.success) {
          const { token, userInfo } = response.data.data;
          
          // 保存到本地存储
          wx.setStorageSync('token', token);
          wx.setStorageSync('userInfo', userInfo);
          
          // 保存到全局数据
          const app = getApp();
          app.globalData.token = token;
          app.globalData.userInfo = userInfo;
          
          resolve(response.data);
        } else {
          reject(new Error(response.data ? response.data.message : '微信登录失败'));
        }
      },
      fail: (error) => {
        reject(new Error('网络请求失败：' + error.errMsg));
      }
    });
  });
};

/**
 * 普通登录函数
 * @param {string} phone 手机号
 * @param {string} password 密码
 * @returns {Promise<Object>} 返回登录结果
 */
const login = (phone, password) => {
  return new Promise((resolve, reject) => {
    wx.request({
      url: `${getApiBaseUrl()}/auth/phone_login`,
      method: 'POST',
      data: { phone, password },
      success: (response) => {
        if (response.data && response.data.success) {
          const { token, userInfo } = response.data.data;
          
          // 保存到本地存储
          wx.setStorageSync('token', token);
          wx.setStorageSync('userInfo', userInfo);
          
          // 保存到全局数据
          const app = getApp();
          app.globalData.token = token;
          app.globalData.userInfo = userInfo;
          
          resolve(response.data);
        } else {
          reject(new Error(response.data ? response.data.message : '登录失败'));
        }
      },
      fail: (error) => {
        reject(new Error('网络请求失败：' + error.errMsg));
      }
    });
  });
};

/**
 * 用户注册函数
 * @param {Object} userData 注册数据
 * @returns {Promise<Object>} 返回注册结果
 */
const register = (userData) => {
  return new Promise((resolve, reject) => {
    wx.request({
      url: `${getApiBaseUrl()}/auth/register`,  // 使用通用注册端点
      method: 'POST',
      data: userData,
      success: (response) => {
        if (response.data && response.data.success) {
          const { token, userInfo } = response.data.data;
          
          // 保存到本地存储
          wx.setStorageSync('token', token);
          wx.setStorageSync('userInfo', userInfo);
          
          // 保存到全局数据
          const app = getApp();
          app.globalData.token = token;
          app.globalData.userInfo = userInfo;
          
          resolve(response.data);
        } else {
          reject(new Error(response.data ? response.data.message : '注册失败'));
        }
      },
      fail: (error) => {
        reject(new Error('网络请求失败：' + error.errMsg));
      }
    });
  });
};

/**
 * 发送短信验证码
 * @param {string} phone 手机号
 * @param {string} type 验证码类型（register/login/reset）
 * @returns {Promise<Object>} 返回发送结果
 */
const sendSmsCode = (phone, type = 'register') => {
  return new Promise((resolve, reject) => {
    wx.request({
      url: `${getApiBaseUrl()}/auth/send_sms`,
      method: 'POST',
      data: { phone, type },
      success: (response) => {
        if (response.data && response.data.success) {
          resolve(response.data);
        } else {
          reject(new Error(response.data ? response.data.message : '发送验证码失败'));
        }
      },
      fail: (error) => {
        reject(new Error('网络请求失败：' + error.errMsg));
      }
    });
  });
};

/**
 * 开发模式测试登录函数
 * @returns {Promise<Object>} 返回登录结果包含token和openid
 */
const testLogin = () => {
  return new Promise((resolve, reject) => {
    // 使用测试code进行登录
    wx.request({
      url: `${getApp().globalData.apiBaseUrl}/auth/login`,
      method: 'POST',
      data: { code: 'test_code_123' },
      success: (response) => {
        if (response.data && response.data.success) {
          const app = getApp();
          app.globalData.token = response.data.data.token;
          app.globalData.openid = response.data.data.openid;
          
          // 保存到本地存储
          wx.setStorageSync('token', response.data.data.token);
          wx.setStorageSync('openid', response.data.data.openid);
          
          resolve(response.data.data);
        } else {
          reject(new Error(response.data ? response.data.message : '测试登录失败'));
        }
      },
      fail: (error) => {
        reject(new Error('测试登录网络请求失败：' + error.errMsg));
      }
    });
  });
};

/**
 * 获取存储的token
 * @returns {string|null} 返回token或null
 */
const getToken = () => {
  const app = getApp();
  return app.globalData.token || wx.getStorageSync('token');
};

/**
 * 清除token
 */
const clearToken = () => {
  const app = getApp();
  app.globalData.token = null;
  app.globalData.openid = null;
  app.globalData.studentInfo = null;
  wx.removeStorageSync('token');
  wx.removeStorageSync('openid');
  wx.removeStorageSync('studentInfo');
};

/**
 * 检查是否已登录
 * @returns {boolean} 是否已登录
 */
const isLoggedIn = () => {
  return !!getToken();
};

/**
 * 检查用户是否已绑定学生
 * @returns {boolean} 是否已绑定学生
 */
const isStudentBound = () => {
  const userInfo = wx.getStorageSync('userInfo');
  return !!(userInfo && BIND_SUCCESS_STATUSES.includes(userInfo.bind_status) && (userInfo.studentInfo || userInfo.student));
};

/**
 * 绑定学生信息
 * @param {Object} bindData 绑定数据
 * @returns {Promise<Object>} 绑定结果
 */
const bindStudent = (bindData) => {
  return new Promise((resolve, reject) => {
    const token = getToken();
    if (!token) {
      reject(new Error('未登录，请先登录'));
      return;
    }
    
    wx.request({
      url: `${getApp().globalData.apiBaseUrl}/auth/bind`,
      method: 'POST',
      header: {
        'Authorization': `Bearer ${token}`
      },
      data: bindData,
      success: (res) => {
        if (res.data.success) {
          const app = getApp();
          const bindResult = res.data.data;
          
          // 更新学生信息
          if (bindResult.student) {
            app.globalData.studentInfo = bindResult.student;
            wx.setStorageSync('studentInfo', bindResult.student);
          }
          
          // 更新用户信息
          const currentUserInfo = wx.getStorageSync('userInfo') || {};
          const updatedUserInfo = {
            ...currentUserInfo,
            bind_status: bindResult.bind_status,
            student_id: bindResult.student_id,
            studentInfo: bindResult.student
          };
          
          wx.setStorageSync('userInfo', updatedUserInfo);
          app.globalData.userInfo = updatedUserInfo;
          
          resolve(bindResult);
        } else {
          reject(new Error(res.data.message || '绑定失败'));
        }
      },
      fail: (error) => {
        reject(new Error('绑定失败：' + error.errMsg));
      }
    });
  });
};

/**
 * 获取用户信息
 * @returns {Promise<Object>} 用户信息
 */
const getUserProfile = () => {
  return new Promise((resolve, reject) => {
    const token = getToken();
    if (!token) {
      reject(new Error('未登录，请先登录'));
      return;
    }

    const apiBase = getApp().globalData.apiBaseUrl;

    // 优先调用包含 avatar 等完整资料的 /user/profile，如果失败再回退 /auth/profile
    const fetchFull = () => new Promise((res, rej) => {
      wx.request({
        url: `${apiBase}/user/profile`,
        method: 'GET',
        header: { 'Authorization': `Bearer ${token}` },
        success: (r) => {
          if (r.statusCode === 200 && r.data && r.data.success) res(r.data.data); else rej(new Error(r.data && r.data.message || 'full_profile_failed'));
        },
        fail: (e) => rej(new Error(e.errMsg || 'full_profile_req_fail'))
      });
    });

    const fetchBasic = () => new Promise((res, rej) => {
      wx.request({
        url: `${apiBase}/auth/profile`,
        method: 'GET',
        header: { 'Authorization': `Bearer ${token}` },
        success: (r) => {
          if (r.data && r.data.success) res(r.data.data); else rej(new Error(r.data && r.data.message || 'basic_profile_failed'));
        },
        fail: (e) => rej(new Error(e.errMsg || 'basic_profile_req_fail'))
      });
    });

    (async () => {
      let profile = null;
      try {
        profile = await fetchFull();
      } catch (_e) {
        try {
          const basic = await fetchBasic();
          // basic 中可能没有 avatar / nickname 等，保持字段存在避免覆盖掉之前缓存
          const cached = wx.getStorageSync('userInfo') || {};
            profile = { ...cached, ...basic };
        } catch (inner) {
          reject(inner);
          return;
        }
      }

      // 兼容：确保 avatar / avatarUrl 同步（若存在）
      if (profile && profile.avatar && !profile.avatarUrl) {
        profile.avatarUrl = profile.avatar;
      }

      wx.setStorageSync('userInfo', profile);
      const app = getApp();
      app.globalData.userInfo = profile;
      resolve(profile);
    })();
  });
};

/**
 * 退出登录函数
 * @returns {Promise<void>}
 */
const logout = () => {
  return new Promise((resolve, reject) => {
    try {
      // 清除本地存储的登录信息与用户资料
      wx.removeStorageSync('token');
      wx.removeStorageSync('openid');
      wx.removeStorageSync('userInfo');
      wx.removeStorageSync('studentInfo');
      
      // 清除全局数据
      const app = getApp();
      app.globalData.token = null;
      app.globalData.openid = null;
      app.globalData.userInfo = null;
      app.globalData.studentInfo = null;
      
      resolve();
    } catch (error) {
      reject(new Error('退出登录失败：' + error.message));
    }
  });
};

/**
 * 统一计算与归一化用户状态
 * @param {Object|null} userInfo 原始userInfo
 * @returns {{status:string,userInfo:Object|null}}
 */
const computeUserStatus = (userInfo) => {
  const token = getToken();
  if (!token) return { status: 'visitor', userInfo: null };
  if (!userInfo) {
    userInfo = wx.getStorageSync('userInfo') || null;
  }
  if (!userInfo) return { status: 'visitor', userInfo: null };
  // 归一化 studentInfo
  if (!userInfo.studentInfo && userInfo.student) {
    userInfo = { ...userInfo, studentInfo: userInfo.student };
  }
  let status = 'registered';
  if (userInfo.studentInfo && BIND_SUCCESS_STATUSES.includes(userInfo.bind_status)) {
    status = 'complete';
  }
  // 写回本地（归一化）
  wx.setStorageSync('userInfo', userInfo);
  return { status, userInfo };
};

// 兼容旧页面：快速获取当前已缓存的用户信息（不触发网络请求）
const getCurrentUser = () => {
  const info = wx.getStorageSync('userInfo') || null;
  if (!info) return null;
  if (!info.studentInfo && info.student) {
    return { ...info, studentInfo: info.student };
  }
  return info;
};

// 统一导出（CommonJS）
module.exports = {
  wechatLogin,
  login,
  register,
  sendSmsCode,
  testLogin,
  getToken,
  clearToken,
  isLoggedIn,
  isStudentBound,
  BIND_SUCCESS_STATUSES,
  bindStudent,
  getUserProfile,
  logout,
  computeUserStatus,
  getCurrentUser
};